#region Using Statements
using System;
using System.Collections;
using Core.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Core.Graphics.Layers;
#endregion

namespace Core.Mapping
{
    /// <summary>
    /// This is a THE Map Engine.  Draws the map.
    /// </summary>
    public partial class MapEngine
    {
        /// <summary>Enable/Disable TileMap</summary>
        public bool Enable { get { return _Enable; } set { _Enable = value; } }
        /// <summary>Number of pixels to offset the map in the x axis during drawing when we are scrolling</summary>
        public int MapSubX { get { return _MapSubX; } }
        /// <summary>Number of pixels to offset the map in the Y axis during drawing when we are scrolling</summary>
        public int MapSubY { get { return _MapSubY; } }
        /// <summary>Map's Position in Pixels From Left of Screen</summary>
        public int Left { get { return _Left; } set { _Left = value; } }
        /// <summary>Map's Position in Pixels From Top of Screen</summary>
        public int Top { get { return _Top; } set { _Top = value; } }
        /// <summary>Number of Tiles Wide to display the map</summary>
        public int Width { get { return _DrawWidth; } set { _DrawWidth = value; } }
        /// <summary>Number of Tiles High to display the map</summary>
        public int Height { get { return _DrawHeight; } set { _DrawHeight = value; } }
        /// <summary>How many tiles in x and y away from the current coordinate should we start drawing the map</summary>
        public Point MapCenterOffset { get { return _MapCenterOffset; } }

        protected int _MapSubX;
        protected int _MapSubY;
        protected int _Left, _Top;
        protected int _DrawWidth, _DrawHeight;
        protected Point _MapCenterOffset;
        protected int iXLoc, iYLoc;
        protected bool _Enable;

        public MapEngine()
        {
            _Enable = true;
        }      

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public void Update(GameTime gameTime)
        {
            if (_Enable)
            {
                UpdateMapCenterOffset();
            }
        }

        public void UpdateMapCenterOffset()
        {
            _MapCenterOffset = new Point(_DrawWidth / 2, _DrawHeight / 2);
        }

        public void DrawMap(MapLayerBaseTypes order, SpriteBatch spriteBatch, Rectangle currentView, ArrayList Maps)
        {
            DrawMap(order, spriteBatch, currentView, Maps, Tile.ScaledTileWidth, Tile.ScaledTileHeight);
        }

        public void DrawMap(MapLayerBaseTypes order, SpriteBatch spriteBatch, Rectangle currentView, ArrayList Maps, int ScaleHeight, int ScaleWidth)
        {
            if (_Enable)
            {
                Rectangle dView = new Rectangle(currentView.X, currentView.Y, currentView.Width, currentView.Height);

                spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

                foreach (Map tm in Maps)
                {
                    int x = tm.WorldX;
                    int y = tm.WorldY;

                    Point world = new Point(x, y);

                    //Our initial draw area will be the whole map.
                    Rectangle drawArea = new Rectangle(x, y, Map.MapWidth, Map.MapHeight);
                    //Our corrected Drawing area will be intersection rectangle between two viewable area and map area rectangles
                    drawArea = RectangleTools.Intersect(drawArea, dView);
                    //Get map Layers to cycle through
                    LayerCollection mapLayers = tm.GetLayersByBaseType(order);

                   foreach (TileLayer tml in mapLayers)
                    {
                        DrawLayer(tml, spriteBatch, drawArea, currentView, world, ScaleHeight, ScaleWidth);
                    }
                }
                spriteBatch.End();
            }
        }

        public void DrawLayer(TileLayer tml, SpriteBatch spriteBatch, Rectangle drawArea, Rectangle currentView, Point WorldCoordinate, int ScaleHeight, int ScaleWidth)
        {
            for (int y = 0; y < drawArea.Height; y++)
            {
                for (int x = 0; x < drawArea.Width; x++)
                {
                    //  Take the current row, multiply it by the width of a row, and then add the column value.
                    Tile TerrainTile = tml.Tiles[Map.MapWidth * (drawArea.Y - WorldCoordinate.Y + y) +
                        drawArea.X - WorldCoordinate.X + x];
                    //If this is not a blank tile
                    if (TerrainTile.SpriteID.ID != TileID.EmptyID.ID)
                    {
                        //Create Destination Drawing Rectangle
                        Rectangle recDest = new Rectangle(
                            (((Math.Abs(currentView.X - drawArea.X) + x) * ScaleWidth) + _Left) - _MapSubX,
                            (((Math.Abs(currentView.Y - drawArea.Y) + y) * ScaleHeight) + _Top) - _MapSubY,
                            ScaleWidth, ScaleHeight);

                        //Draw Sprite to screen
                        TerrainTile.Draw(spriteBatch, recDest);
                    }
                }
            }
        }
    }
}


